﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using ComplexNetCentralityLib;
using QuickGraph;
using QuickGraph.Serialization;
using QuickGraphBuilder;
using EpidemicSimulator;
using GraphMLComplexType;
using EdgeWithAttributes;


namespace ComplexNetCentralityTest
{
    class Program
    {
        public static void writeGraphML(AdjacencyGraph<SocialNetworkNode, EdgeWithAttributes<SocialNetworkNode>> graph, String path)
        {
            var vertexIdentity = new VertexIdentity<SocialNetworkNode>(SocialNetworkNode.vertexIdentity);
            var edgeIdentity = new EdgeIdentity<SocialNetworkNode, EdgeWithAttributes<SocialNetworkNode>>(SocialNetworkNode.edgeIdentity<SocialNetworkNode, EdgeWithAttributes<SocialNetworkNode>>);

            using (var writer = new XmlTextWriter(path, Encoding.UTF8))
            {
                writer.WriteStartDocument();
                graph.SerializeToGraphML(writer, vertexIdentity, edgeIdentity);
            }
        }

        static void Main(string[] args)
        {
            Console.Write("podaj nazwe pliku graphml: ");
            string path = System.Console.ReadLine();
            string graphml;
            try
            {
                graphml = new StreamReader(File.OpenRead(path)).ReadToEnd();
            }
            catch(Exception e)
            {
                Console.WriteLine("blad! zla nazwa pliku");
                Console.ReadKey();
                return;
            }
            var network = GraphMLBuilder.Build<SocialNetworkNode>(graphml, "/");
            int p10 = network.VertexCount/10;
            Console.WriteLine();
            Console.WriteLine("Trwaja obliczenia...");
            DateTime startTime = DateTime.Now;
            StreamWriter writer = new StreamWriter("output.txt", false, Encoding.UTF8);
            Console.SetOut(writer);
            //-------------------------------------------------------------------------
            AdjacencyGraph<IGraphMLComplexType, EdgeWithAttributes<IGraphMLComplexType>> net1 = new AdjacencyGraph<IGraphMLComplexType, EdgeWithAttributes<IGraphMLComplexType>>();
            foreach (Edge<SocialNetworkNode> edge in network.Edges)
            {
                net1.AddVerticesAndEdge(new EdgeWithAttributes<IGraphMLComplexType>(edge.Source, edge.Target));
            }

            Console.WriteLine("punkt 1");
            Console.WriteLine("WEJSCIE: siec SF (N=" + network.VertexCount + ", m0=1, M=1)");
            Console.WriteLine("WYJSCIE: GCE sieci w.w. sieci");
            Console.WriteLine("|> GCE = " + ConnectionEfficiency.globalConnectionEfficiency(net1));
            Console.WriteLine();
            //-------------------------------------------------------------------------
            AdjacencyGraph<IGraphMLComplexType, EdgeWithAttributes<IGraphMLComplexType>> net2 = new AdjacencyGraph<IGraphMLComplexType, EdgeWithAttributes<IGraphMLComplexType>>();
            foreach (Edge<SocialNetworkNode> edge in network.Edges)
            {
                net2.AddVerticesAndEdge(new EdgeWithAttributes<IGraphMLComplexType>(edge.Source, edge.Target));
            }

            Console.WriteLine("punkt 2");
            Console.WriteLine("WEJSCIE: siec z punktu 1, usuwam losowo 10% wezlow");
            Console.WriteLine("WYJSCIE: GCE sieci po usunieciu wezlow");
            Console.WriteLine("|> GCE = " + ConnectionEfficiency.vaccinateRandom(net2,p10));
            Console.WriteLine();
            //-------------------------------------------------------------------------
            AdjacencyGraph<IGraphMLComplexType, EdgeWithAttributes<IGraphMLComplexType>> net3 = new AdjacencyGraph<IGraphMLComplexType, EdgeWithAttributes<IGraphMLComplexType>>();
            foreach (Edge<SocialNetworkNode> edge in network.Edges)
            {
                net3.AddVerticesAndEdge(new EdgeWithAttributes<IGraphMLComplexType>(edge.Source, edge.Target));
            }

            Console.WriteLine("punkt 3");
            Console.WriteLine("WEJSCIE: siec z punktu 1, usuwam 10% wezlow o najwyższej wartosci degree centrality");
            Console.WriteLine("WYJSCIE: GCE sieci po usunieciu wezlow");
            Console.WriteLine("|> GCE = " + ConnectionEfficiency.vaccinateByDegreeCentrality(net3, p10));
            Console.WriteLine();
            //-------------------------------------------------------------------------
            AdjacencyGraph<IGraphMLComplexType, EdgeWithAttributes<IGraphMLComplexType>> net4 = new AdjacencyGraph<IGraphMLComplexType, EdgeWithAttributes<IGraphMLComplexType>>();
            foreach (Edge<SocialNetworkNode> edge in network.Edges)
            {
                net4.AddVerticesAndEdge(new EdgeWithAttributes<IGraphMLComplexType>(edge.Source, edge.Target));
            }

            Console.WriteLine("punkt 4");
            Console.WriteLine("WEJSCIE: siec z punktu 1, usuwam 10% wezlow o najwyższej wartosci betweenness centrality");
            Console.WriteLine("WYJSCIE: GCE sieci po usunieciu wezlow");
            Console.WriteLine("|> GCE = " + ConnectionEfficiency.vaccinateByBetweennessCentrality(net4, p10));
            Console.WriteLine();
            //-------------------------------------------------------------------------
            AdjacencyGraph<IGraphMLComplexType, EdgeWithAttributes<IGraphMLComplexType>> net5 = new AdjacencyGraph<IGraphMLComplexType, EdgeWithAttributes<IGraphMLComplexType>>();
            foreach (Edge<SocialNetworkNode> edge in network.Edges)
            {
                net5.AddVerticesAndEdge(new EdgeWithAttributes<IGraphMLComplexType>(edge.Source, edge.Target));
            }

            Console.WriteLine("punkt 5");
            Console.WriteLine("WEJSCIE: siec z punktu 1, losuje 10% wezlow i usuwam losowego sasiada dla wylosowanego wezla");
            Console.WriteLine("WYJSCIE: GCE sieci po usunieciu wezlow");
            Console.WriteLine("|> GCE = " + ConnectionEfficiency.vaccinateNaighbour(net5, p10));
            Console.WriteLine();
            //-------------------------------------------------------------------------            
            writer.Close();
            var sw = new StreamWriter(Console.OpenStandardOutput());
            sw.AutoFlush = true;
            Console.SetOut(sw);
            DateTime stopTime = DateTime.Now;
            TimeSpan computeTime = stopTime - startTime;
            Console.WriteLine("Obliczenia trwaly: "+computeTime);
            Console.WriteLine("Wynik zapisany do pliku output.txt");
            Console.ReadKey();
        }

        
    }
}
